What is detective-amd?
The detective-amd package is designed for analyzing AMD (Asynchronous Module Definition) style modules. It allows developers to parse AMD module definitions to extract dependencies, providing a way to understand and manipulate the dependency tree of projects using this module format.
What are detective-amd's main functionalities?
Extracting dependencies from AMD modules
This feature allows you to pass AMD module source code as a string to the detective function, which returns an array of the module's dependencies. It's useful for analyzing and understanding module dependencies.
const detective = require('detective-amd');
const src = "define(['a', 'b'], function (a, b) {});";
const dependencies = detective(src);
// dependencies would be ['a', 'b']
Other packages similar to detective-amd
madge
Madge is a tool for generating a visual graph of module dependencies, or finding circular dependencies in JavaScript and TypeScript projects. It supports AMD, CommonJS, and ES6 module formats. Compared to detective-amd, Madge offers a broader range of functionalities including visualization and support for multiple module formats.
dependency-tree
dependency-tree is a utility for generating a tree of dependencies for a given file. It supports various module formats including AMD, CommonJS, and ES6. Unlike detective-amd, which focuses on AMD modules, dependency-tree provides a more general approach to dependency analysis across different module types.
Detective-AMD
Returns a list of dependencies for a given JavaScript file or AST using any of the AMD module syntaxes.
Inspired by substack/node-detective but built for AMD.
npm install detective-amd
Usage
Let's say we have the following file definitions:
define(['./b', './c'], function (b, c) {
console.log(b, c);
});
define({
name: 'foo'
});
define(function () {
return 'bar';
});
Here's how you can grab the list of dependencies of a.js
synchronously.
const detective = require('detective-amd');
const srca = fs.readFileSync('a.js', 'utf8');
console.log(detective(srca));
You may also (optionally) configure the detective via a second object argument detective(src, options)
that supports the following options:
skipLazyLoaded
: (Boolean) whether or not to omit inner requires in the list of extracted dependencies.
- Note: this does not affect the REM form since those inner requires are not "lazily" fetched.
Syntax Support
Supports the 4 forms of AMD module syntax:
- "named":
define('name', [deps], func)
- "dependency list":
define([deps], func)
- "factory":
define(func(require))
- "no dependencies":
define({})
Extra forms:
- "driver script" (or entry-point) syntax:
require([deps], func)
- "REM" (or CommonJS-like) form:
define(function(require, exports, module) {})
.
Also handles dynamically loaded dependencies (ex: inner requires).
Supports driver scripts
You can also find the dependencies from a script that has a top-level require (an app initialization/driver/entry-point script):
require([
'./a'
], function (a) {
});
Expression-based requires
If there's a require call that doesn't have a string literal but an expression,
a string (escodegen-generated) representation will be returned.
For example, if a.js
was of the "factory" form and contained a dynamic module name:
define(function (require) {
const b = require('./' + str);
const c = require('./c');
console.log(b, c);
});
The dependency list will be: [ '\'./\' + str', './c' ]
- Even though that string representation isn't incredibly useful, it's
still added to the list to represent/count that dependency